package com.ce.util.chart;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.ce.framework.util.StringUtil;

public class Element {

	private String tagName;
	private String text;

	private HashMap<String,String> attribute = new HashMap<String,String>();
	private List<Element> children = new ArrayList<Element>();

	public Element(String tagName) {
		super();
		this.tagName = tagName;
	}

	public Element(String tagName, String text) {
		super();
		this.tagName = tagName;
		this.text = text;
	}

	public Element addChild(String tagName){
		Element e = new Element(tagName,"");
		children.add(e);
		return e;
	}

	public Element addChild(String tagName,String text){
		Element e = new Element(tagName,text);
		children.add(e);
		return e;
	}

	public Element addChild(Element e){
		children.add(e);
		return e;
	}

	public Element addChild(int index,Element e){
		children.add(index, e);
		return e;
	}

	public Element addXPathChild(String xpath){
		if(StringUtil.isBlank(xpath))
			return this;
		String[] tmp = xpath.split("/");
		Element e = this;
		for(int i=0;i<tmp.length;i++){
			if(StringUtil.isBlank(tmp[i]))
				continue;
			Element tmpe = e.getFirstChild(tmp[i]);
			if(tmpe==null){
				tmpe = e.addChild(tmp[i]);
			}
			e = tmpe;
		}
		return e;
	}

	public Element setChild(int index,Element e){
		children.set(index, e);
		return e;
	}
	
	public boolean hasChild(String tagName){
		return this.children.contains(new Element(tagName));
	}
	
	public Element getFirstChild(String tagName){
		if(children.isEmpty())
			return null;
		if(StringUtil.isBlank(tagName)){
			return children.get(0);
		}
		for(Element e:children){
			if(tagName.equals(e.getTagName())){
				return e;
			}
		}
		return null;
	}

	public Element remove(int index){
		return children.remove(index);
	}

	public Element remove(Element e){
		children.remove(e);
		return e;
	}

	public Element setAttribute(String name,String value){
		attribute.put(name, value);
		return this;
	}

	public String removeAttribute(String name){
		return attribute.remove(name);
	}

	public void setCDATA(String cdata){
		this.text = "<![CDATA["+cdata+"]]>";
	}
	
	public String getCDATA(){
		if(this.text.startsWith("<![CDATA[")&&this.text.endsWith("]]>")){
			return this.text.substring(9,text.length()-3);
		}
		return text;
	}
	
	public String toString(){
		StringBuffer buff = new StringBuffer("<").append(tagName);
		Iterator<String> it = attribute.keySet().iterator();
		String key,val;
		while(it.hasNext()){
			key = it.next();val = attribute.get(key);
			if(StringUtil.isNotBlank(key)&&StringUtil.isNotBlank(val)){
				buff.append(" "+key+"=\"").append(val).append("\"");
			}
		}
		buff.append(">");
		if(children.isEmpty()){
			buff.append(text==null?"":text);
		}
		else{
			buff.append("\n");
			for(Element e:children){
				buff.append(e.toString());
			}
		}
		buff.append("</"+tagName+">\n");
		return buff.toString();
	}

	public String getTagName() {
		return tagName;
	}

	public void setTagName(String tagName) {
		this.tagName = tagName;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public List<Element> getChildren() {
		return children;
	}

	public HashMap<String, String> getAttribute() {
		return attribute;
	}

	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Element))
			return false;
		return this.tagName!=null&&this.tagName.equals(((Element)obj).getTagName());
	}

}
